#include<p24fj128ga006.h>
#include <libpic30.h>
#include "data_process.h"


/*******************************************************
 Data processing UART1 
 <02><from><to><type><len><Pload><03>
 <From>  - 00 -> PC
           01 -> Device
 <to>    - 00 -> PC
           01 -> Device
 <type>  - 00 -> x
           01 -> x
           02 -> Cmd
           03 -> Reply
           0A -> Ack
           0B -> Nack
 <len>  -  data length
 <Pload>-  <type of data><data>
              00 -> x
              01 -> Get Mac Addr
              02 -> Get Grants list
              03 -> Get Report list
                         <data>
                           00 -> Onu1
                           01 -> Onu2
                           0N -> Onu N  
              04 -> Get counter32 value
              05 -> Put Q list(ONU only)
              06 -> Get Q list(OLT only)
              07 -> request new Q (device --> PC)
              08 -> Delay status
                      <time start><time stop> -- 8 byte
              09 -> DBA wasted bandwidth
                      <data1><data2> -- 2 byte
            
 <03>
*******************************************************/

void process_URX1(void)//input from feeder
{
   if(URX1_Ready == 0x01)
   {       
      if((in1_buffer[1]==0x00)&&(in1_buffer[2]==0x01))
      {
          Reply_URX1();
      }   
       URX1_Ready = 0x00;
   }   
}

/************************************************************
Process optical data receive

*************************************************************/

void process_URX2(void)//input from optical module
{
   int i;
   unsigned long int timer_counter32_temp;
   //unsigned char temp[50];

   if(URX2_Ready == 0x01)
   {
 
       //check llid if equal to system send back onu only
       //.....
       //.....
       //other
       //U1TXREG = 0x85; //debug
      // SChar(in2_buffer[10]);//debug
       if(   (in2_buffer[9] ==  ONU_MACAddr[0])&& (in2_buffer[10] ==  ONU_MACAddr[1])&&(in2_buffer[11] ==  ONU_MACAddr[2])
           &&(in2_buffer[12] ==  ONU_MACAddr[3])&&(in2_buffer[13] ==  ONU_MACAddr[4])&&(in2_buffer[14] == ONU_MACAddr[5]))//check DA
       {   
                 
               
           //check length/type
           if((in2_buffer[21] ==  0x88)&& (in2_buffer[22] ==  0x08))//88-08 - MPCP
           {
               // U1TXREG = 0x86;
                //Check opcode
                //if((in2_buffer[23] == 0x00) && (in2_buffer[24] == 0x01))//Pulse
                //{                
                //}
                
                 //copy timestemp to time register
                 timer_counter32_temp = in2_buffer[28];
                 timer_counter32_temp = in2_buffer[27] | (timer_counter32_temp <<8);
                 timer_counter32_temp = in2_buffer[26] | (timer_counter32_temp <<16);
                 timer_counter32_temp = in2_buffer[25] | (timer_counter32_temp <<24);
                 timer_counter32 = timer_counter32_temp; 
                 //end
                if((in2_buffer[23] == 0x00) && (in2_buffer[24] == 0x02))//Grand
                {
                   
                   //check grant flag if empty exti not process
                   if((in2_buffer[23] & 0x07)== 0x07)//alive receive
                   {                                          
                      //empty_grant_f = 0x01;  
                      goto exit;//exit
                   }
                   else
                   { 
                      //SChar('B');//debug   
                      grants_list[0] = 0x01; 
                      //grants_list[1] = 0x02;//data len
                   
                      for(i=0;i<39;i++)//copy from in buffer
                      {
                         grants_list[i+1] =  in2_buffer[29+i]; 
                      }
                      
                   }
                
                }
                ///if((in2_buffer[23] == 0x00) && (in2_buffer[24] == 0x03))//Report
                ///{   
               ////}
                //else if((in2_buffer[23] == 0x00) && (in2_buffer[24] == 0x04))//Reg_req
                //{
                  //send to Discovery agent controller    
                //}
                //else if((in2_buffer[23] == 0x00) && (in2_buffer[24] == 0x05))//Reg
                //{
                   //send to Discovery agent controller     
                //}
                //else if((in2_buffer[23] == 0x00) && (in2_buffer[24] == 0x06))//Reg_ack
                //{
                   //send to Discovery agent controller     
                //}
                else//opcode not supported
                {
                  in2_buffer[0]= 0x00;// discard frame
                  //exit(1);// break;
                }
exit:
                //send copy to utx1
                for(i=0;i<0x49;i++)
                {
                    U1TXREG = in2_buffer[i];      
                    __delay32(1500); 
                }
                in2_buffer[0] = 0x00; 
                time_stamp();//send time stamps                
           }
           else//data with length
           {
              for(i=0;i<in2_buffer[5];i++)//length/type != mac client pass to mac client
              {
                 U1TXREG = in2_buffer[i];      
                 __delay32(1500); 
              }
           }
           
       }
       /* //cancel for only dedicated data 
       else//send to feeder 
       {
   
           for(i=0;i<0x49;i++)//pass to mac client
           {
              U1TXREG = in2_buffer[i];      
              __delay32(1500); 
           }

       }*/
    //U2TXREG = 0x88;//debug
    URX2_Ready = 0x00;   
   }
   else if(URX2_Ready == 0x02)//receive data 
   {
       for(i=0;i<length_type;i++)//send to feeder utx1
       {
          U1TXREG = in2_buffer[i];      
          __delay32(1500);
       }
       URX2_Ready = 0x00;
   }
}




/********************************************************************************

Reply data -> to PC (UART1)

*********************************************************************************/

void Reply_URX1(void)
{
   int i;
   unsigned char *temp_store;


   switch(in1_buffer[5])
   {  
       //U1TXREG = 'A';    
       case 0x01://reply mac addr
              in1_buffer[0] = 0x02; //start of data 
              in1_buffer[1] = 0x01; //from device
              in1_buffer[2] = 0x00; //to PC
              in1_buffer[3] = 0x03; //reply
              
              in1_buffer[5] = 0x01; //get MAC addr
              for(i=0;i<6;i++)
              {
                in1_buffer[i+6] = ONU_MACAddr[i]; //get MAC addr
              }
              in1_buffer[4] = i+1; //length 
              in1_buffer[i+6] = 0x03; //end of data
         break;
       case 0x02://reply get grants list info only at onu
              in1_buffer[0] = 0x02; //start of data 
              in1_buffer[1] = 0x01; //from device
              in1_buffer[2] = 0x00; //to PC
              in1_buffer[3] = 0x03; //reply
              in1_buffer[5] = 0x02; //get grant data
              for(i=0;i<26;i++)
              {
                in1_buffer[i+6] = grants_list[i]; //load grants buffer
              }
              in1_buffer[4] = i+1; //length 
              in1_buffer[i+6] = 0x03; //end of data
         break;
       case 0x03://Get Report list (OLT Only)
              in1_buffer[0] = 0x02; //start of data 
              in1_buffer[1] = 0x01; //from device
              in1_buffer[2] = 0x00; //to PC
              in1_buffer[3] = 0x0B; //reply
              in1_buffer[4] = 0x01; //length
              in1_buffer[5] = in1_buffer[5]; //reply grants list(NACK)                          
              in1_buffer[6] = 0x03; //end of data
         break; 
       case 0x04://get counter32 value
              in1_buffer[0] = 0x02; //start of data 
              in1_buffer[1] = 0x01; //from device
              in1_buffer[2] = 0x00; //to PC
              in1_buffer[3] = 0x03; //reply
              
              in1_buffer[5] = 0x04; //get counter32 value

              temp_store = changeLong2Byte(timer_counter32); 
              for(i=0;i<4;i++)
              {
                in1_buffer[i+6] = temp_store[i]; //load timer value
              }
              in1_buffer[4] = i+1; //length
              in1_buffer[i+6] = 0x03; //end of data
         break;  
       case 0x05://Put Q list(ONU only)

              //copy to queue_list
              queue_list[0] = 0x01;//flag for report ready
              for(i=1;i<17;i++)
              {
                 queue_list[i] = in1_buffer[i+6];
              }
        
              //send ack cmd
              in1_buffer[0] = 0x02; //start of data 
              in1_buffer[1] = 0x01; //from device
              in1_buffer[2] = 0x00; //to PC
              in1_buffer[3] = 0x0A; //reply   
              in1_buffer[4] = 0x01; //len      
              in1_buffer[5] = in1_buffer[5]; //type of data ack     (this case remain type)                  
              in1_buffer[6] = 0x03; //end of data
         break;
       case 0x06://Get Q list(OLT & ONU) for debug function
              in1_buffer[0] = 0x02; //start of data 
              in1_buffer[1] = 0x01; //from device
              in1_buffer[2] = 0x00; //to PC
              in1_buffer[3] = 0x03; //reply
              
              in1_buffer[5] = in1_buffer[5]; //reply grants list(NACK) 
              for(i=0;i<16;i++)
              {
                in1_buffer[i+6] = queue_list[i]; //load timer value
              }
              in1_buffer[4] = i+1; //length
              in1_buffer[i+6] = 0x03; //end of data                         
              
         break;
      // case 0x08://delay
      //        in1_buffer[0] = 0x02; //start of data 
      //        in1_buffer[1] = 0x01; //from device
      //        in1_buffer[2] = 0x00; //to PC
     //         in1_buffer[3] = 0x03; //reply
      //        in1_buffer[4] = 0x01; //length
      //        in1_buffer[5] = 0x08; //delay 
      //        //start time
      //        //stop time                        
      //        in1_buffer[6] = 0x03; //end of data
      //   break;     
       case 0x00:case 0x07:case 0x08:case 0x09:case 0x0A:case 0x0B: //not used 
              in1_buffer[0] = 0x02; //start of data 
              in1_buffer[1] = 0x01; //from device
              in1_buffer[2] = 0x00; //to PC
              in1_buffer[3] = 0x0B; //reply
              in1_buffer[4] = 0x01; //length
              in1_buffer[5] = in1_buffer[5]; //reply grants list(NACK)                          
              in1_buffer[6] = 0x03; //end of data
         break;
         //goto exit;      
       
   }
   //send to PC
   send_URX1();
//exit:
//  Nop();
  
}

void send_URX1(void)
{
    int i;
 
    for(i=0;i<in1_buffer[4]+6;i++)
    {
         U1TXREG = in1_buffer[i];               
         __delay32(1500); 
    }
    in1_buffer[0]= 0x00; 
    in1_buffer[in1_buffer[4]+5]= 0x00; 


}


void chk_report_buffer(void)
{
    if(queue_list[0] == 0x02)//send request q to pc
    {
        in1_buffer[0] = 0x02; //start of data 
        in1_buffer[1] = 0x01; //from device
        in1_buffer[2] = 0x00; //to PC
        in1_buffer[3] = 0x02; //cmd
        in1_buffer[4] = 0x01; //length
        in1_buffer[5] = 0x07; //request q                        
        in1_buffer[6] = 0x03; //end of data

        queue_list[0]=0x00;
        send_URX1();
    }
}
